import { unique } from './array'
import { isArray, isString } from './types'

/**
 * 根据位置,使用 * 遮蔽字符串
 * @param {string} cc
 * @param {number} num1
 * @param {number} num2
 * @param {string} _mask
 * @example utilscore.mask('12398765432',3,7) // => "123****5432"
 */
export const mask = (cc, num1 = 0, num2 = 0, _mask = '*') => {
  let reg = new RegExp(`\^\(\.\{${num1}\}\)\(\.\{${num2 - num1}\}\)\(\.${num2>=cc.length?'\?':'\+'}\)\$`);
  return cc.replace(reg,($0,$1,$2,$3)=> $1+$2.replace(/./g,_mask)+$3)
}

/**
 * 从位置左边开始，使用 * 遮蔽字符串
 * @param {string} cc
 * @param {number} num
 * @param {string} _mask
 * @example 用法跟 mask 类似
 */
export const maskLeft = (cc, num = 0, _mask = '*') => mask(cc,0,num,_mask)

/**
 * 从位置右边开始，使用 * 遮蔽字符串
 * @param {string} cc
 * @param {number} num
 * @param {string} _mask
 * @example 用法跟 mask 类似
 */
export const maskRight = (cc, num = 0, _mask = '*') => {
  let strL = cc.length
  return mask(cc,num>strL?0:strL-num,strL,_mask)
}


/**
 * 生成一个随机的十六进制颜色代码
 * @example utilscore.randomHexColorCode() // => "#c4aabc"
 */
export const randomHexColorCode = () => {
    let n = ((Math.random() * 0xfffff) | 0).toString(16);
    return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n)
  }


/**
 * 返回元素出现的次数
 * @param {string} str
 * @param {null|string,array} keys
 * @example 1.不传参,获取全部
              utilscore.getCounts('asawdawf') // => {a: 3, s: 1, w: 2, d: 1, f: 1}
            2.传字符串
              utilscore.getCounts('asasfdfasdasf','asf') // => {asf: 2}
            3.传数组
              utilscore.getCounts('asdfjl;qwoetuqwe*(^&&()_)*_23480*yoij)(ojilA4WE4',['we*(^&&()_)*','asdfjl','_23480','qw'])
              // => {we*(^&&()_)*: 1, asdfjl: 1, _23480: 1, qw: 2}
 */
export const getCounts = (str,keys=null) => {
  let arr = {}
  let keyMap = []
  let arrStr = str.split('')

  if(isArray(keys)) keyMap = unique(keys);
  else if(isString(keys)) keyMap = keys.split(' ')
  else keyMap = unique(arrStr)

  keyMap.map(key=>{

    //处理包含特殊字符
    var reg = new RegExp("\([`~!@#$^&*()=|{}':;',\\[\\].<>/?~！@#￥……&*（）——|{}【】‘；：”“'。，、？]\)",'g')
    let _key = key.replace(reg,'\\$1')

    let res = str.match(new RegExp(_key,'g'))

    arr[key] = res?(arr[key] = res.length):0
  })


	return arr
}

/**
 * 全局唯一标识符 UUID
 * @param {number} len 长度
 * @param {number} radix 基数 62
 * @example utilscore.uuid(10,62) // => "e424F79HP8"
 */
export const uuid = (len, radix) => {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  var uuid = [], i;
  radix = radix || chars.length;

  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
  } else {
    // rfc4122, version 4 form
    var r;

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';

    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random()*16;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
  }

  return uuid.join('');
}

/**
 * GUID:128位的数字标识符
 * @example utilscore.guid() // => "537a3b5a-5c1b-433d-9814-532efdda6b10"
 */
export const guid = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
      return v.toString(16);
  });
}

export const format=(val,...args)=>{
	  return val.replace(/{(\d+)}/g, function(match, number) {
	    return typeof args[number] !== 'undefined' ? args[number] : match
	  })
}
export const Trim =function (val,c=null) {
	if (c == null || c == "") {
			var str = val.replace(/^s*/, '');
			var rg = /s/;
			var i = str.length;
			while (rg.test(str.charAt(--i)));
			return str.slice(0, i + 1);
	}
	else {
			var rg = new RegExp("^" + c + "*");
			var str = val.replace(rg, '');
			rg = new RegExp(c);
			var i = str.length;
			while (rg.test(str.charAt(--i)));
			return str.slice(0, i + 1);
	}
}

//去除字符串头部空格或指定字符
export const TrimStart = function (val,c=null) {
	if (c == null || c == "") {
			var str = val.replace(/^s*/, '');
			return str;
	}
	else {
			var rg = new RegExp("^" + c + "*");
			var str = val.replace(rg, '');
			return str;
	}
}

//去除字符串尾部空格或指定字符
export const TrimEnd = function (val,c=null) {
	if (c == null || c == "") {
			var str = val;
			var rg = /s/;
			var i = str.length;
			while (rg.test(str.charAt(--i)));
			return str.slice(0, i + 1);
	}
	else {
			var str = val;
			var rg = new RegExp(c);
			var i = str.length;
			while (rg.test(str.charAt(--i)));
			return str.slice(0, i + 1);
	}
}
export const replaceAll =function(val,str1,str2){
	return val.replace(new RegExp(str1,"gm"),str2);
}

export const clearHtmlTag=function(html){
	return replaceAll(html,/<[^>]+>/g,"");
}
// 字符串加密成 hex 字符串
export const  sha1 = (s) => {
  var data = new Uint8Array(encodeUTF8(s))
  var i, j, t;
  var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
  s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
  for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
  s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
  s[l - 1] = data.length << 3;
  var w = [], f = [
    function () { return m[1] & m[2] | ~m[1] & m[3]; },
    function () { return m[1] ^ m[2] ^ m[3]; },
    function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
    function () { return m[1] ^ m[2] ^ m[3]; }
  ], rol = function (n, c) { return n << c | n >>> (32 - c); },
    k = [1518500249, 1859775393, -1894007588, -899497514],
    m = [1732584193, -271733879, null, null, -1009589776];
  m[2] = ~m[0], m[3] = ~m[1];
  for (i = 0; i < s.length; i += 16) {
    var o = m.slice(0);
    for (j = 0; j < 80; j++)
      w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
        t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
        m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
    for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
  };
  t = new DataView(new Uint32Array(m).buffer);
  for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);

  var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
    return (e < 16 ? "0" : "") + e.toString(16);
  }).join("");
  return hex;
}
/**
 * 评分组件
 * @param {Number} rate max 5
 * @example utilscore.getRate(2)   //★★☆☆☆
 */
export const getRate =  (rate) => {
    return '★★★★★☆☆☆☆☆'.slice(5 - rate, 10 - rate);
}
export const valueToString = (obj) => Object.values(obj).sort().join('')
export const generate = (length = 16) => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let noceStr = '', maxPos = chars.length;
    while (length--) noceStr += chars[Math.random() * maxPos | 0];
    return noceStr;
}
export const encodeUTF8 = (s) => {
  var i, r = [], c, x;
  for (i = 0; i < s.length; i++)
    if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
    else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
    else {
      if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
        c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
          r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
      else r.push(0xE0 + (c >> 12 & 0xF));
      r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
    };
  return r;
}